<!DOCTYPE html>
<html lang=zh>
<head>
    <!-- so meta -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="HandheldFriendly" content="True">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5" />
    <meta name="description" content="什么是 webpack先看看 webpack 官方文档的解释：  webpack is a static module bundler for modern JavaScript applications.  翻译成中文的意思就是：webpack 是一个为现代 JavaScript 应用的静态打包工具。 这里面有几个重要的名词：static 、module 、bundler 、modern  st">
<meta property="og:type" content="article">
<meta property="og:title" content="webpack 入门">
<meta property="og:url" content="https://danyuan30.gitee.io/2022/02/05/frontend/webpack/index.html">
<meta property="og:site_name" content="柯里的语法糖">
<meta property="og:description" content="什么是 webpack先看看 webpack 官方文档的解释：  webpack is a static module bundler for modern JavaScript applications.  翻译成中文的意思就是：webpack 是一个为现代 JavaScript 应用的静态打包工具。 这里面有几个重要的名词：static 、module 、bundler 、modern  st">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220102112311888.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107203826906.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107203948463.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107182632060.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107183032354.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107183149372.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107183702178.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107184455918.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107184546229.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107191156568.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107191831993.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107193450326.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107194648139.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107201912032.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107202339104.png">
<meta property="og:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107202626573.png">
<meta property="article:published_time" content="2022-02-05T06:19:40.068Z">
<meta property="article:modified_time" content="2022-02-18T01:31:18.394Z">
<meta property="article:author" content="柯里的语法糖">
<meta property="article:tag" content="webpack">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220102112311888.png">
    
    
      
        
          <link rel="shortcut icon" href="https://codertzm.oss-cn-chengdu.aliyuncs.com/favicon.ico">
        
      
      
        
          <link rel="icon" type="image/png" href="https://codertzm.oss-cn-chengdu.aliyuncs.com/favicon.ico" sizes="192x192">
        
      
      
        
          <link rel="apple-touch-icon" sizes="180x180" href="https://codertzm.oss-cn-chengdu.aliyuncs.com/favicon.ico">
        
      
    
    <!-- title -->
    <title>webpack 入门</title>
    <!-- styles -->
    
<link rel="stylesheet" href="/css/style.css">

    <!-- persian styles -->
    
    <!-- rss -->
    
    
	<!-- mathjax -->
	
<meta name="generator" content="Hexo 6.0.0"></head>

<body class="max-width mx-auto px3 ltr">
    
      <div id="header-post">
  <a id="menu-icon" href="#" aria-label="Menu"><i class="fas fa-bars fa-lg"></i></a>
  <a id="menu-icon-tablet" href="#" aria-label="Menu"><i class="fas fa-bars fa-lg"></i></a>
  <a id="top-icon-tablet" href="#" aria-label="Top" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');" style="display:none;"><i class="fas fa-chevron-up fa-lg"></i></a>
  <span id="menu">
    <span id="nav">
      <ul>
        <!--
       --><li><a href="/">首页</a></li><!--
     --><!--
       --><li><a href="/tags/">标签</a></li><!--
     --><!--
       --><li><a href="/categories/">分类</a></li><!--
     --><!--
       --><li><a href="/archives/">归档</a></li><!--
     --><!--
       --><li><a target="_blank" rel="noopener" href="http://github.com/twitzz">项目</a></li><!--
     --><!--
       --><li><a href="/about/">关于</a></li><!--
     --><!--
       --><li><a href="/search/">搜索</a></li><!--
     -->
      </ul>
    </span>
    <br/>
    <span id="actions">
      <ul>
        
        <li><a class="icon" aria-label="上一篇" href="/2022/02/05/grow/2021/"><i class="fas fa-chevron-left" aria-hidden="true" onmouseover="$('#i-prev').toggle();" onmouseout="$('#i-prev').toggle();"></i></a></li>
        
        
        <li><a class="icon" aria-label="下一篇" href="/2022/02/05/frontend/vuex_map/"><i class="fas fa-chevron-right" aria-hidden="true" onmouseover="$('#i-next').toggle();" onmouseout="$('#i-next').toggle();"></i></a></li>
        
        <li><a class="icon" aria-label="返回顶部" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fas fa-chevron-up" aria-hidden="true" onmouseover="$('#i-top').toggle();" onmouseout="$('#i-top').toggle();"></i></a></li>
        <li><a class="icon" aria-label="分享文章" href="#"><i class="fas fa-share-alt" aria-hidden="true" onmouseover="$('#i-share').toggle();" onmouseout="$('#i-share').toggle();" onclick="$('#share').toggle();return false;"></i></a></li>
      </ul>
      <span id="i-prev" class="info" style="display:none;">上一篇</span>
      <span id="i-next" class="info" style="display:none;">下一篇</span>
      <span id="i-top" class="info" style="display:none;">返回顶部</span>
      <span id="i-share" class="info" style="display:none;">分享文章</span>
    </span>
    <br/>
    <div id="share" style="display: none">
      <ul>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.facebook.com/sharer.php?u=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/"><i class="fab fa-facebook " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://twitter.com/share?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&text=webpack 入门"><i class="fab fa-twitter " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.linkedin.com/shareArticle?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&title=webpack 入门"><i class="fab fa-linkedin " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://pinterest.com/pin/create/bookmarklet/?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&is_video=false&description=webpack 入门"><i class="fab fa-pinterest " aria-hidden="true"></i></a></li>
  <li><a class="icon" href="mailto:?subject=webpack 入门&body=Check out this article: https://danyuan30.gitee.io/2022/02/05/frontend/webpack/"><i class="fas fa-envelope " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://getpocket.com/save?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&title=webpack 入门"><i class="fab fa-get-pocket " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://reddit.com/submit?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&title=webpack 入门"><i class="fab fa-reddit " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.stumbleupon.com/submit?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&title=webpack 入门"><i class="fab fa-stumbleupon " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://digg.com/submit?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&title=webpack 入门"><i class="fab fa-digg " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.tumblr.com/share/link?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&name=webpack 入门&description="><i class="fab fa-tumblr " aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://news.ycombinator.com/submitlink?u=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&t=webpack 入门"><i class="fab fa-hacker-news " aria-hidden="true"></i></a></li>
</ul>

    </div>
    <div id="toc">
      <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF-webpack"><span class="toc-number">1.</span> <span class="toc-text">什么是 webpack</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#webpack-%E5%87%BA%E7%8E%B0%E5%89%8D%E5%AD%98%E5%9C%A8%E5%93%AA%E4%BA%9B%E9%97%AE%E9%A2%98"><span class="toc-number">1.1.</span> <span class="toc-text">webpack 出现前存在哪些问题</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#webpack-%E7%9A%84%E5%AE%89%E8%A3%85"><span class="toc-number">2.</span> <span class="toc-text">webpack 的安装</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#webpack-%E7%9A%84%E9%BB%98%E8%AE%A4%E6%89%93%E5%8C%85"><span class="toc-number">3.</span> <span class="toc-text">webpack 的默认打包</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%A5%E5%8F%A3%E4%B8%8E%E5%87%BA%E5%8F%A3"><span class="toc-number">3.1.</span> <span class="toc-text">入口与出口</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B1%80%E9%83%A8%E4%BD%BF%E7%94%A8-webpack"><span class="toc-number">4.</span> <span class="toc-text">局部使用 webpack</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#webpack-%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="toc-number">5.</span> <span class="toc-text">webpack 的配置文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#webpack-%E7%9A%84%E4%BE%9D%E8%B5%96"><span class="toc-number">6.</span> <span class="toc-text">webpack 的依赖</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AFloader"><span class="toc-number">7.</span> <span class="toc-text">什么是loader</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#loader%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">8.</span> <span class="toc-text">loader的配置</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#loader-%E7%9A%84%E9%85%8D%E7%BD%AE%E9%A1%BA%E5%BA%8F"><span class="toc-number">9.</span> <span class="toc-text">loader 的配置顺序</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#less-%E7%9A%84%E5%A4%84%E7%90%86"><span class="toc-number">10.</span> <span class="toc-text">less 的处理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#less-loader"><span class="toc-number">10.1.</span> <span class="toc-text">less-loader</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#PostCSS-%E9%85%8D%E7%BD%AE"><span class="toc-number">11.</span> <span class="toc-text">PostCSS  配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#PostCSS-%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E4%BD%BF%E7%94%A8"><span class="toc-number">11.1.</span> <span class="toc-text">PostCSS 的命令行使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#postcss-loader"><span class="toc-number">11.2.</span> <span class="toc-text">postcss-loader</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E7%9A%84%E6%89%93%E5%8C%85"><span class="toc-number">12.</span> <span class="toc-text">静态资源的打包</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Plugin"><span class="toc-number">13.</span> <span class="toc-text">Plugin</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#CleanWebpackPlugin"><span class="toc-number">13.1.</span> <span class="toc-text">CleanWebpackPlugin</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8"><span class="toc-number">13.1.1.</span> <span class="toc-text">使用</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#HtmlWebpackPlugin"><span class="toc-number">13.2.</span> <span class="toc-text">HtmlWebpackPlugin</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89HTML%E6%A8%A1%E6%9D%BF"><span class="toc-number">13.2.1.</span> <span class="toc-text">自定义HTML模板</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#DefinePlugin"><span class="toc-number">13.3.</span> <span class="toc-text">DefinePlugin</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#CopyWebpackPlugin"><span class="toc-number">13.4.</span> <span class="toc-text">CopyWebpackPlugin</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#mode%E9%85%8D%E7%BD%AE"><span class="toc-number">14.</span> <span class="toc-text">mode配置</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#babel-%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">15.</span> <span class="toc-text">babel 的配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E4%BD%BF%E7%94%A8"><span class="toc-number">15.1.</span> <span class="toc-text">babel 的命令行使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-%E6%8F%92%E4%BB%B6"><span class="toc-number">15.2.</span> <span class="toc-text">babel 插件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-%E9%A2%84%E8%AE%BE"><span class="toc-number">15.3.</span> <span class="toc-text">babel 预设</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-%E7%9A%84%E5%BA%95%E5%B1%82%E5%8E%9F%E7%90%86"><span class="toc-number">15.4.</span> <span class="toc-text">babel 的底层原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-loader"><span class="toc-number">15.5.</span> <span class="toc-text">babel-loader</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="toc-number">15.6.</span> <span class="toc-text">babel 的配置文件</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AF%B9-vue-%E6%96%87%E4%BB%B6%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">16.</span> <span class="toc-text">对 vue 文件的配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#vue-%E6%89%93%E5%8C%85%E5%90%8E%E4%B8%8D%E5%90%8C%E7%89%88%E6%9C%AC%E8%A7%A3%E6%9E%90"><span class="toc-number">16.1.</span> <span class="toc-text">vue 打包后不同版本解析</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#vue-%E4%B8%AD-%E8%BF%90%E8%A1%8C%E6%97%B6-%E7%BC%96%E8%AF%91%E5%99%A8-vs-%E4%BB%85%E8%BF%90%E8%A1%8C%E6%97%B6"><span class="toc-number">16.2.</span> <span class="toc-text">vue 中 运行时 + 编译器 vs 仅运行时</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#devServer-%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">17.</span> <span class="toc-text">devServer 的配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#webpack-watch"><span class="toc-number">17.1.</span> <span class="toc-text">webpack watch</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#HMR%EF%BC%88-%E6%A8%A1%E5%9D%97%E7%83%AD%E6%9B%BF%E6%8D%A2-%EF%BC%89"><span class="toc-number">17.2.</span> <span class="toc-text">HMR（ 模块热替换 ）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#HMR-%E7%9A%84%E5%8E%9F%E7%90%86"><span class="toc-number">17.3.</span> <span class="toc-text">HMR 的原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#devServer%E4%B8%AD%E7%9A%84%E5%85%B6%E4%BB%96%E9%85%8D%E7%BD%AE"><span class="toc-number">17.4.</span> <span class="toc-text">devServer中的其他配置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#proxy"><span class="toc-number">17.5.</span> <span class="toc-text">proxy</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#resolve-%E6%A8%A1%E5%9D%97%E8%A7%A3%E6%9E%90"><span class="toc-number">18.</span> <span class="toc-text">resolve 模块解析</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A7%A3%E6%9E%90%E8%BF%87%E7%A8%8B"><span class="toc-number">18.1.</span> <span class="toc-text">解析过程</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#resolve-%E4%B8%AD%E7%9A%84-extensions-%E4%B8%8E-alias-%E9%85%8D%E7%BD%AE"><span class="toc-number">18.2.</span> <span class="toc-text">resolve 中的 extensions 与 alias 配置</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#webpack-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E7%9A%84%E5%88%86%E7%A6%BB"><span class="toc-number">19.</span> <span class="toc-text">webpack 配置文件的分离</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%BB%E7%BB%93"><span class="toc-number">20.</span> <span class="toc-text">总结</span></a></li></ol>
    </div>
  </span>
</div>

    
    <div class="content index py4">
        
        <article class="post" itemscope itemtype="http://schema.org/BlogPosting">
  <header>
    
    <h1 class="posttitle" itemprop="name headline">
        webpack 入门
    </h1>



    <div class="meta">
      <span class="author" itemprop="author" itemscope itemtype="http://schema.org/Person">
        <span itemprop="name">柯里的语法糖</span>
      </span>
      
    <div class="postdate">
      
        <time datetime="2022-02-05T06:19:40.068Z" itemprop="datePublished">2022-02-05</time>
        
      
    </div>


      
    <div class="article-category">
        <i class="fas fa-archive"></i>
        <a class="category-link" href="/categories/%E5%AE%9E%E6%88%98%E5%BC%80%E5%8F%91/">实战开发</a>
    </div>


      
    <div class="article-tag">
        <i class="fas fa-tag"></i>
        <a class="tag-link-link" href="/tags/webpack/" rel="tag">webpack</a>
    </div>


    </div>
  </header>
  

  <div class="content" itemprop="articleBody">
    <h2 id="什么是-webpack"><a href="#什么是-webpack" class="headerlink" title="什么是 webpack"></a>什么是 webpack</h2><p>先看看 <code>webpack</code> 官方文档的解释：</p>
<blockquote>
<p><strong>webpack</strong> is a <em>static module bundler</em> for modern JavaScript applications.</p>
</blockquote>
<p>翻译成中文的意思就是：<code>webpack</code> 是一个为现代 <code>JavaScript</code> 应用的静态打包工具。</p>
<p>这里面有几个重要的名词：<code>static</code> 、<code>module</code> 、<code>bundler</code> 、<code>modern</code></p>
<ul>
<li><code>static</code>：表示静态资源，最终将它们部署到服务器上</li>
<li><code>module</code>：表示默认支持模块化开发，如：<code>CommonJS</code> 、<code>ES Module</code> 等</li>
<li><code>bundler</code>：表示这是一个打包工具</li>
<li><code>modern</code>：表示现代前端的发展存在很多问题，正是因为有这些问题，才催生了 <code>webpack</code> 的出现</li>
</ul>
<h3 id="webpack-出现前存在哪些问题"><a href="#webpack-出现前存在哪些问题" class="headerlink" title="webpack 出现前存在哪些问题"></a>webpack 出现前存在哪些问题</h3><p>如今的前端开发已经变得越来越复杂，需要考虑很多东西，如：模块化开发、使用高级特性来提高开发效率、对代码进行压缩、实施监听文件变化提高开发效率。</p>
<p>这个时候 <code>webpack</code> 出现了。</p>
<p>如今的前端三大框架 <code>Vue</code> 、<code>React</code> 、<code>Angular</code> 的创建使用都是基于脚手架（CLI），但其实，CLI都是 <strong>基于webpack</strong> 来帮助我们支持上述功能。</p>
<h2 id="webpack-的安装"><a href="#webpack-的安装" class="headerlink" title="webpack 的安装"></a>webpack 的安装</h2><p><code>webpack</code> 的安装分为两个：<code>webpack</code>、<code>webpack-cli</code></p>
<p><strong>它们之间的关系是这样的：</strong></p>
<ul>
<li>在执行webpack命令的时候，会执行 <code>node_modules</code> 下的 <code>.bin</code> 目录下的 <code>webpack</code></li>
<li><code>webpack</code> 在执行的时候，依赖 <code>webpack-cli</code> ，如果没有安装则会报错</li>
<li>而 <code>webpack-cli</code> 中的代码在执行的时候，才是真正利用了 <code>webpack</code> 的编译和打包</li>
</ul>
<h2 id="webpack-的默认打包"><a href="#webpack-的默认打包" class="headerlink" title="webpack 的默认打包"></a>webpack 的默认打包</h2><p>在项目目录下，我们可以直接在终端中，执行 <code>webpack</code> 命令。</p>
<p>此时会生成一个 <code>dist</code> 文件夹，里面会存放 <code>main.js</code> 文件。这就是 <code>webpack</code> 的出口文件。</p>
<h3 id="入口与出口"><a href="#入口与出口" class="headerlink" title="入口与出口"></a>入口与出口</h3><p>当我们运行 <code>webpack</code> 命令的时候，它会查找当前目录下的 <code>src/index.js</code> 文件作为入口文件。</p>
<p>并且会将打包生成 <code>dist/main.js</code> 文件，作为出口文件。</p>
<p>在这个 <code>main.js</code> 文件中，它默认会对代码进行压缩和丑化。</p>
<h2 id="局部使用-webpack"><a href="#局部使用-webpack" class="headerlink" title="局部使用 webpack"></a>局部使用 webpack</h2><p>可以通过 <code>npx webpack</code> 命令执行，它会执行 <code>node_modules</code> 下的 <code>.bin</code> 目录下的 <code>webpack</code>。</p>
<p>也可以通过在 <code>package.json</code> 文件中，创建 <code>scripts</code> 脚本，执行打包。</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&quot;scripts&quot;</span>: &#123;</span><br><span class="line">  <span class="attr">&quot;build&quot;</span>: <span class="string">&quot;webpack&quot;</span></span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h2 id="webpack-的配置文件"><a href="#webpack-的配置文件" class="headerlink" title="webpack 的配置文件"></a>webpack 的配置文件</h2><p>webpack需要打包的项目是非常复杂的，并且我们需要一系列的配置来满足要求。</p>
<p>我们可以在根目录下创建一个 <code>webpack.config.js</code> 文件，来作为 <code>webpack</code> 的配置文件：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">&#x27;path&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  <span class="comment">// 配置入口文件</span></span><br><span class="line">  <span class="attr">entry</span>: <span class="string">&#x27;./src/index.js&#x27;</span>,</span><br><span class="line">  <span class="comment">// 配置出口文件</span></span><br><span class="line">  <span class="attr">output</span>: &#123;</span><br><span class="line">    <span class="comment">// 绝对路径   dirname获取当前文件所在的路径</span></span><br><span class="line">    <span class="attr">path</span>: path.resolve(__dirname, <span class="string">&#x27;./dist&#x27;</span>),</span><br><span class="line">    <span class="comment">// 打包的文件名</span></span><br><span class="line">    <span class="attr">filename</span>: <span class="string">&#x27;main.js&#x27;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="webpack-的依赖"><a href="#webpack-的依赖" class="headerlink" title="webpack 的依赖"></a>webpack 的依赖</h2><p><code>webpack</code> 在处理应用程序时，它会根据命令或者配置文件找到入口文件。</p>
<p>从入口开始，会生成一个 依赖关系图，这个依赖关系图会包含应用程序中所需的所有模块（比如.js文件、css文件、图片、字体等）。</p>
<p>然后遍历图结构，打包一个个模块（根据文件的不同使用不同的 <code>loader</code> 来解析）。</p>
<p><strong><code>webpack</code> 的官方图：</strong></p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220102112311888.png" alt="image-20220102112311888"></p>
<h2 id="什么是loader"><a href="#什么是loader" class="headerlink" title="什么是loader"></a>什么是loader</h2><p><code>loader</code> 可以用于对模块的源代码进行转换，</p>
<p>我们可以将 <code>css</code> 文件也看成是一个模块，如果我们现在在一个 <code>js</code> 文件中，写如下的代码用于引入 <code>css</code> 文件：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="string">&#x27;./css/style.css&#x27;</span></span><br></pre></td></tr></table></figure>

<p>此时我们进行打包的时候，是会报错的。</p>
<p>因为在加载这个模块的时候，<code>webpack</code> 是不知道如何对其进行加载的。我们需要使用对应的 <code>loader</code> 来完成这个加载的功能。</p>
<h2 id="loader的配置"><a href="#loader的配置" class="headerlink" title="loader的配置"></a>loader的配置</h2><p>如果需要加载 <code>css</code> 文件模块，需要使用 <code>css-loader</code>。</p>
<p>   在引入的文件前，加上使用的 <code>loader</code> ，并使用 ! 分割</p>
   <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="string">&#x27;css-loader!./css/style.css&#x27;</span></span><br></pre></td></tr></table></figure>

<ol start="2">
<li><p>配置方式<strong>（推荐）</strong></p>
<p><code>module.rules</code>  中允许配置多个 <code>loader</code></p>
<p><code>rules</code> 对应的值是一个数组：数组中是一个个的对象，对象中可以设置多个属性：</p>
<ul>
<li><code>test</code> 属性：用于对 resource（资源）进行匹配的，通常会设置成正则表达式</li>
<li><code>use</code> 属性：对应的是一个数组，数组中的每个元素是对象，对象的属性包括<ul>
<li><code>loader</code>：必须有一个 loader属性，对应的值是一个字符串</li>
<li><code>options</code>：可选的属性，值是一个字符串或者对象，值会被传入到loader中</li>
</ul>
</li>
<li><code>loader</code>属性： <code>Rule.use: [ &#123; loader &#125; ]</code> 的简写</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">module</span>：&#123;</span><br><span class="line">  <span class="attr">rules</span>:[</span><br><span class="line">    &#123;</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="comment">// 正则表达式</span></span><br><span class="line">        <span class="attr">test</span>: <span class="regexp">/\.css$/</span>,</span><br><span class="line">        <span class="comment">// 第一种写法 语法糖</span></span><br><span class="line">        <span class="comment">// loader: &#x27;css-loader&#x27;,</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 第二种写法 完整写法</span></span><br><span class="line">        use: [</span><br><span class="line">          &#123;</span><br><span class="line">            <span class="attr">loader</span>: <span class="string">&#x27;css-loader&#x27;</span>,</span><br><span class="line">          &#125;,</span><br><span class="line">        ],</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;</span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li>
</ol>
<p>配置完成，重新打包后，我们会发现样式并没有生效，这是因为 <code>css-loader</code> 只是<strong>负责将.css文件进行解析</strong>，并不会将解析之后的css插入到页面中。</p>
<p>如果我们需要完成插入<code>style</code> 的操作，需要使用 <code>style-loader</code> 。</p>
<h2 id="loader-的配置顺序"><a href="#loader-的配置顺序" class="headerlink" title="loader 的配置顺序"></a>loader 的配置顺序</h2><p><code>loader</code> 的配置是需要考虑顺序的，比如 <code>style-loader</code> 的使用是需要建立在有 <code>css-loader</code>  的基础上的。</p>
<p>因为loader的执行顺序是从后到前，所以我们需要将 <code>style-loader</code> 写到 <code>css-loader</code> 的前面；</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">use: [</span><br><span class="line">  <span class="string">&#x27;style-loader&#x27;</span>,</span><br><span class="line">  <span class="string">&#x27;css-loader&#x27;</span></span><br><span class="line">],</span><br></pre></td></tr></table></figure>

<h2 id="less-的处理"><a href="#less-的处理" class="headerlink" title="less 的处理"></a>less 的处理</h2><p>在实际开发中，我们可能会使用 <code>less</code>、<code>sass</code> 这样的预处理器，（这里以 <code>less</code> 为例）因此我们需要一个将<code>less</code> 转换为 <code>css</code> 文件的编译工具。</p>
<p>我们可以使用 <code>less</code> 工具完成编译：</p>
<p>安装：</p>
<p><code>npm install less -D</code></p>
<p>执行如下命令，进行编译转换：</p>
<p><code>npx lessc &#39;less文件&#39; &#39;css文件&#39;</code></p>
<h3 id="less-loader"><a href="#less-loader" class="headerlink" title="less-loader"></a>less-loader</h3><p>但是，在实际开发中，我们需要编写很多的 <code>less</code> 文件，如果全部进行手动编译，是不现实的。因此，我们需要 <code>less-loader</code> 来帮助我们完成自动编译。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="attr">test</span>:<span class="regexp">/\.less$/</span>,</span><br><span class="line">  use: [</span><br><span class="line">    <span class="string">&#x27;less-loader&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;style-loader&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;css-loader&#x27;</span></span><br><span class="line">  ],</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="PostCSS-配置"><a href="#PostCSS-配置" class="headerlink" title="PostCSS  配置"></a>PostCSS  配置</h2><p><code>PostCSS</code> 是一个通过 <code>JavaScript</code> 来转换样式的工具，可以帮助我们进行一些CSS的转换和适配，比如自动添加浏览器前缀、css样式的重置。</p>
<p>但是实现这些功能，我们需要借助于PostCSS对应的插件。</p>
<p>在 <code>webpack</code> 中，可以通过 <code>postcss-loader</code> 来使用，然后选择需要的 <code>PostCSS</code> 相关的插件。</p>
<h3 id="PostCSS-的命令行使用"><a href="#PostCSS-的命令行使用" class="headerlink" title="PostCSS 的命令行使用"></a>PostCSS 的命令行使用</h3><p>在命令行中也是可以使用 <code>PostCSS</code> 的。</p>
<p>首先安装：</p>
<p><code>npm install postcss postcss-cli -D</code></p>
<p>假如我们现在需要为 <code>css</code> 属性添加浏览器前缀，那么我们需要安装 <code>autoprefixer</code> 插件：</p>
<p><code>npm install autoprefixer -D</code></p>
<p>执行命令：</p>
<p><code>npx postcss --use autoprefixer -o end.css ./src/css/style.css</code></p>
<h3 id="postcss-loader"><a href="#postcss-loader" class="headerlink" title="postcss-loader"></a>postcss-loader</h3><p>在实际开发中，肯定是不会用命令行来对 <code>css</code> 进行处理，在 <code>webpack</code> 中，使用 <code>postcss-loader</code> 可以达到这样的效果。</p>
<p>安装：</p>
<p><code>npm install postcss-loader -D</code></p>
<p>配置：</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107203826906.png" alt="image-20220107203826906"></p>
<p>也可以将这些配置信息单独放在一个配置文件 ( postcss.config.js ) 中管理：</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107203948463.png" alt="image-20220107203948463"></p>
<h2 id="静态资源的打包"><a href="#静态资源的打包" class="headerlink" title="静态资源的打包"></a>静态资源的打包</h2><p>如果我们需要在项目中使用静态资源（ 如：图片，字体等 ），也需要对它进行打包的处理。</p>
<p>在 <code>webpack5</code> 之前，加载这些资源我们需要使用一些 <code>loader</code>，比如 <code>raw-loader</code> 、<code>url-loader</code>、<code>file-loader</code> 。</p>
<p>从 <code>webpack5</code> 开始，我们可以直接使用资源模块（ asset module type ），来代替上面的这些 <code>loader</code> 。</p>
<p>资源模块类型( asset module type )，通过添加 4 种新的模块类型，来替换所有这些 <code>loader</code>：</p>
<ul>
<li><p><strong>asset/resource</strong> 发送一个单独的文件并导出 URL。之前通过使用 <code>file-loader</code> 实现；</p>
</li>
<li><p><strong>asset/inline</strong> 导出一个资源的 data URI。之前通过使用 <code>url-loader</code> 实现；</p>
</li>
<li><p><strong>asset/source</strong> 导出资源的源代码。之前通过使用 <code>raw-loader</code> 实现；</p>
</li>
<li><p><strong>asset</strong> 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader，并且配置资源体积限制实现；</p>
</li>
</ul>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  test: /\.(jpe?g|png|gif|svg)$/,</span><br><span class="line">  type: <span class="string">&quot;asset&quot;</span>,</span><br><span class="line">  generator: &#123;</span><br><span class="line">    <span class="comment">// 设置生成的文件名和在哪个文件夹下面</span></span><br><span class="line">    <span class="comment">// 其中img/为文件夹名称 </span></span><br><span class="line">    <span class="comment">// [name] 原文件名</span></span><br><span class="line">    <span class="comment">// [hash:xxx] 设置的hash值</span></span><br><span class="line">    <span class="comment">// [ext] 文件扩展名</span></span><br><span class="line">    filename: <span class="string">&quot;img/[name]_[hash:6][ext]&quot;</span></span><br><span class="line">  &#125;,</span><br><span class="line">  parser: &#123;</span><br><span class="line">    dataUrlCondition: &#123;</span><br><span class="line">      <span class="comment">// 设置需要转换base64的文件大小最大值</span></span><br><span class="line">      maxSize: <span class="number">100</span> * <span class="number">1024</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure>

<h2 id="Plugin"><a href="#Plugin" class="headerlink" title="Plugin"></a>Plugin</h2><p><code>webpack</code> 的另一个核心概念是 <code>Plugin</code> 。</p>
<p><code>Loader</code> 仅仅是用于特定的模块类型进行转换。</p>
<p>而 <code>Plugin</code> 可以用于执行更加广泛的任务，如打包优化，资源管理等。</p>
<h3 id="CleanWebpackPlugin"><a href="#CleanWebpackPlugin" class="headerlink" title="CleanWebpackPlugin"></a>CleanWebpackPlugin</h3><p>此插件可以帮助我们打包的时候，自动删除原打包文件夹。</p>
<h4 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h4><p>首先需要使用 <code>npm</code> 安装：</p>
<p><code>npm install clean-webpack-plugin -D</code></p>
<p>接着引入，并在 <code>webpack.config.js</code> 文件中使用：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; CleanWebpackPlugin &#125; = <span class="built_in">require</span>(<span class="string">&quot;clean-webpack-plugin&quot;</span>);</span><br><span class="line">plugins:[</span><br><span class="line">  <span class="keyword">new</span> CleanWebpackPlugin()</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<h3 id="HtmlWebpackPlugin"><a href="#HtmlWebpackPlugin" class="headerlink" title="HtmlWebpackPlugin"></a><strong>HtmlWebpackPlugin</strong></h3><p>此插件是对 <code>index.html</code> 文件进行打包处理。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> HtmlWebpackPlugin()</span><br></pre></td></tr></table></figure>

<h4 id="自定义HTML模板"><a href="#自定义HTML模板" class="headerlink" title="自定义HTML模板"></a>自定义HTML模板</h4><p>如果我们想要在自己的模块中加入一些特别的内容，这时候我们需要一个自己的模板</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> HtmlWebpackPlugin(&#123;</span><br><span class="line">  <span class="attr">template</span>: <span class="string">&quot;./public/index.html&quot;</span>,</span><br><span class="line">  <span class="attr">title</span>: <span class="string">&quot;html文件的标题名&quot;</span></span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<h3 id="DefinePlugin"><a href="#DefinePlugin" class="headerlink" title="DefinePlugin"></a>DefinePlugin</h3><p>此插件可以在编译 <code>template</code> 中的常量，对常量进行解析。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> DefinePlugin(&#123;</span><br><span class="line">  <span class="comment">// 配置全局常量 BASE_URL</span></span><br><span class="line">  <span class="attr">BASE_URL</span>: <span class="string">&quot;&#x27;./&#x27;&quot;</span></span><br><span class="line">&#125;),</span><br></pre></td></tr></table></figure>

<h3 id="CopyWebpackPlugin"><a href="#CopyWebpackPlugin" class="headerlink" title="CopyWebpackPlugin"></a><strong>CopyWebpackPlugin</strong></h3><p>在打包过程中，如果我们想要将一个目录下的文件被复制到 <code>dist</code> 文件夹中，我们可以使用 <code>CopyWebpackPlugin</code> 来完成。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> CopyWebpackPlugin(&#123;</span><br><span class="line">  <span class="comment">// 复制的规则在patterns中设置</span></span><br><span class="line">  <span class="attr">patterns</span>: [</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="comment">// from是原目录</span></span><br><span class="line">      <span class="attr">from</span>: <span class="string">&quot;public&quot;</span>,</span><br><span class="line">      <span class="comment">// to是复制到的目录 默认值是打包的目录</span></span><br><span class="line">      <span class="attr">to</span>: <span class="string">&quot;./&quot;</span>,</span><br><span class="line">      <span class="comment">// globOptions用于设置一些额外的选项，其中可以编写需要忽略的文件：</span></span><br><span class="line">      <span class="attr">globOptions</span>: &#123;</span><br><span class="line">        <span class="attr">ignore</span>: [</span><br><span class="line">          <span class="string">&quot;**/index.html&quot;</span></span><br><span class="line">        ]</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  ]</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<h2 id="mode配置"><a href="#mode配置" class="headerlink" title="mode配置"></a>mode配置</h2><p>mode配置选项，可以告知 <code>webpack</code> 使用响应模式的内置优化。</p>
<p>默认值是  <code>production</code> ，可选值有 <code>none</code> | <code>development</code> | <code>production</code></p>
<p>其中在开发阶段，我们一般设置为 <code>development</code> ，生产阶段设置为 <code>production</code> 。</p>
<blockquote>
<p>注意：mode的配置一旦配置，webpack其实帮我们配置了其他很多东西，如果出现与你的配置重复，则会选择合并，不会覆盖。</p>
</blockquote>
<h2 id="babel-的配置"><a href="#babel-的配置" class="headerlink" title="babel 的配置"></a>babel 的配置</h2><p><code>babel</code> 是一个工具链，主要用于旧浏览器或者环境中将 <code>ES5</code> 之后的代码转换为向后兼容版本的 <code>js</code> 。这其中包括：语法转换、源代码转换等。</p>
<h3 id="babel-的命令行使用"><a href="#babel-的命令行使用" class="headerlink" title="babel 的命令行使用"></a>babel 的命令行使用</h3><p>在命令行中使用 <code>babel</code> ，需要安装 <code>@babel/cli</code> 与 <code>@babel/core</code></p>
<p>命令行：<code>npx babel 源文件目录 --out-dir 输出的目录</code></p>
<h3 id="babel-插件"><a href="#babel-插件" class="headerlink" title="babel 插件"></a>babel 插件</h3><p>如果我们想要转换箭头函数，我们需要使用额外的插件。</p>
<p>箭头函数转换：</p>
<p><code>npm install @babel/plugin-transform-arrow-functions -D</code></p>
<p><code>npx babel src --out-dir dist --plugins=@babel/plugin-transform-arrow-functions</code></p>
<p> 将 <code>const</code> 转换为 <code>var</code> 也需要特定的插件来实现：</p>
<p><code>npm install @babel/plugin-transform-block-scoping -D</code></p>
<p><code>npx babel src --out-dir dist --plugins=@babel/plugin-transform-block-scoping,@babel/plugin-transform-arrow-functions</code></p>
<h3 id="babel-预设"><a href="#babel-预设" class="headerlink" title="babel 预设"></a>babel 预设</h3><p>如果需要转换的内容过多，一个个设置会非常麻烦，我们可以使用预设 ( preset ) 。</p>
<p>安装预设：</p>
<p><code>npm install @babel/preset-env -D</code></p>
<p>执行命令：</p>
<p><code>npx babel src --out-dir dist --presets=@babel/preset-env</code></p>
<h3 id="babel-的底层原理"><a href="#babel-的底层原理" class="headerlink" title="babel 的底层原理"></a>babel 的底层原理</h3><p><code>babel</code> 可以被看做是一个编译器，将我们的源代码，转换成浏览器可以直接识别的另外一段源代码。</p>
<p><code>babel</code> 也有编译器的工作原理:</p>
<ol>
<li>解析阶段 ( Parsing )</li>
<li>转换阶段 ( Transformation )</li>
<li>生成阶段 ( Code Generation )</li>
</ol>
<p><code>babel</code> 执行原理：</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107182632060.png" alt="image-20220107182632060"></p>
<h3 id="babel-loader"><a href="#babel-loader" class="headerlink" title="babel-loader"></a>babel-loader</h3><p>在 <code>webpack</code> 中，我们可以通过配置来使用 <code>babel</code> ，这需要我们安装 <code>@babel/core</code> 与 <code>babel-loader</code> 。</p>
<p>在 <code>webpack.config.js</code> 中，配置 <code>babel-loader</code> ：</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107183032354.png" alt="image-20220107183032354"></p>
<p>通过 <code>options</code> 属性中的 <code>plugins</code> 属性，设置 <code>babel</code> 要使用的插件。</p>
<p>同样，我们也可以配置预设 ( 使用 <code>preset</code> 属性 )：</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107183149372.png" alt="image-20220107183149372"></p>
<h3 id="babel-的配置文件"><a href="#babel-的配置文件" class="headerlink" title="babel 的配置文件"></a>babel 的配置文件</h3><p>我们可以将 <code>babel</code> 的配置信息放在一个独立的文件中，新建：<code>babel.config.js</code> 文件 或者 <code>.babelrc.json</code> 文件。</p>
<p>它们的区别如下：</p>
<p><code>.babelrc.json</code> ：早期使用较多的配置方式，但是对于配置Monorepos项目是比较麻烦的。</p>
<p><code>babel.config.json（babel7）</code>：可以直接作用于Monorepos项目的子包，更加推荐。</p>
<h2 id="对-vue-文件的配置"><a href="#对-vue-文件的配置" class="headerlink" title="对 vue 文件的配置"></a>对 vue 文件的配置</h2><p>和其他文件一样，<code>vue</code> 文件也有自己的 <code>loader</code> —— <code>vue-loader</code> ，来处理文件。</p>
<p>在 <code>webpack.config.js</code> 中配置：</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107183702178.png" alt="image-20220107183702178"></p>
<p>如果我们配置完成后，直接打包会报错，因为我们必须添加 <code>@vue/compiler-sfc</code> 来对 <code>template</code> 进行解析</p>
<p><code>npm install @vue/compiler-sfc -D</code></p>
<p>同时配置对应的插件：</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107184455918.png" alt="image-20220107184455918"></p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107184546229.png" alt="image-20220107184546229"></p>
<h3 id="vue-打包后不同版本解析"><a href="#vue-打包后不同版本解析" class="headerlink" title="vue 打包后不同版本解析"></a>vue 打包后不同版本解析</h3><ul>
<li><strong>vue(.runtime).global(.prod).js：</strong><ul>
<li>通过浏览器中的 <code>&lt;script src=&quot;...&quot;&gt;</code> 直接使用；</li>
<li>我们之前通过CDN引入和下载的Vue版本就是这个版本；</li>
<li>会暴露一个全局的 <code>Vue</code> 来使用；</li>
</ul>
</li>
<li><strong>vue(.runtime).esm-browser(.prod).js：</strong></li>
<li>用于通过原生 ES 模块导入使用 (在浏览器中通过 <code>&lt;script type=&quot;module&quot;&gt;</code> 来使用)。</li>
<li><strong>vue(.runtime).esm-bundler.js</strong>：<ul>
<li>用于 <code>webpack</code>，<code>rollup</code> 和 <code>parcel</code> 等构建工具；</li>
<li>构建工具中默认是 <code>vue.runtime.esm-bundler.js</code> ；</li>
<li>如果我们需要解析模板 <code>template</code> ，那么需要手动指定 <code>vue.esm-bundler.js</code> ；</li>
</ul>
</li>
<li><strong>vue.cjs(.prod).js：</strong><ul>
<li>服务器端渲染使用；</li>
<li>通过 <code>require()</code> 在 <code>Node.js</code> 中使用；</li>
</ul>
</li>
</ul>
<h3 id="vue-中-运行时-编译器-vs-仅运行时"><a href="#vue-中-运行时-编译器-vs-仅运行时" class="headerlink" title="vue 中 运行时 + 编译器 vs 仅运行时"></a>vue 中 运行时 + 编译器 vs 仅运行时</h3><p>在 <code>vue</code> 开发中，有三种方式可以编写 <code>DOM</code> 元素：</p>
<ol>
<li><code>template</code> 模板</li>
<li><code>render</code> 函数</li>
<li>通过 <code>.vue</code> 文件中的 <code>template</code></li>
</ol>
<p>它们的模板分别是如何处理的：</p>
<ol>
<li>需要通过源代码中一部分代码进行解析</li>
<li>通过 <code>vue-loader</code> 进行解析</li>
<li>通过 <code>h</code> 函数返回一个虚拟节点</li>
</ol>
<p><code>vue</code> 在让我们选择版本的时候分为 <strong>运行时 + 编译器</strong> 与 <strong>仅运行时</strong>：</p>
<ul>
<li><strong>运行时 + 编译器</strong> 包含了对 <code>template</code> 模板的编译代码，更加完整，但是也更大一些</li>
<li><strong>仅运行时</strong> 没有包含对 <code>template</code> 版本的编译代码，相对更小一些</li>
</ul>
<h2 id="devServer-的配置"><a href="#devServer-的配置" class="headerlink" title="devServer 的配置"></a>devServer 的配置</h2><p>我们可以通过配置 <strong>本地服务器</strong> 做到：文件发生变化的时候，可以自动完成编译与展示</p>
<p>有如下几种可选方式：</p>
<ul>
<li><code>webapck watch mode</code></li>
<li><code>webpack-dev-server</code>（ 常用 ）</li>
<li><code>webpack-dev-middleware</code></li>
</ul>
<h3 id="webpack-watch"><a href="#webpack-watch" class="headerlink" title="webpack watch"></a>webpack watch</h3><p><code>webpack</code> 为我们提供了 <code>watch</code> 模式，该模式下，<code>webpack</code> 依赖图 中的所有文件，只要有一个发生了变化，那么代码将被重新编译。</p>
<p>开启 <code>watch</code> 模式的两种方式：</p>
<ol>
<li>在配置文件中，加入 <code>watch: true</code></li>
<li>在执行 <code>webapck</code> 的命令中，添加 <code>--watch</code> 标识</li>
</ol>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107191156568.png" alt="image-20220107191156568"></p>
<p>在这种情况下，可以监听到文件的变化，但不会自动刷新浏览器。</p>
<p>我们可以通过安装 <code>webpack-dev-server</code> 来实现：</p>
<p><code>npm install webpack-dev-server -D</code></p>
<p>修改 <code>webpack.config.js</code> 文件：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  <span class="comment">// 设置为 什么东西 打包 node / web </span></span><br><span class="line">  <span class="attr">target</span>: <span class="string">&#x27;web&#x27;</span>,</span><br><span class="line">  <span class="comment">// 配置devServer</span></span><br><span class="line">  <span class="attr">devServer</span>: &#123;</span><br><span class="line">    <span class="comment">// 如果有些资源没有从webpack加载到，就会从contentBase中加载</span></span><br><span class="line">    <span class="attr">contentBase</span>: <span class="string">&quot;./public&quot;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="HMR（-模块热替换-）"><a href="#HMR（-模块热替换-）" class="headerlink" title="HMR（ 模块热替换 ）"></a>HMR（ 模块热替换 ）</h3><p><strong>模块热替换</strong> 是指在 应用程序运行过程中，替换、添加、删除模块，而无需重新刷新整个页面。</p>
<p>默认情况下，<code>webpack-dev-server</code> 已经支持HMR，我们只需要开启即可。</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107191831993.png" alt="image-20220107191831993"></p>
<p>开启后，我们需要指定哪些模块发生更新时，进行 <code>HMR</code>。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(<span class="built_in">module</span>.hot) &#123;</span><br><span class="line">  <span class="built_in">module</span>.hot.accept(<span class="string">&quot;./util.js&quot;</span>, <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&quot;util更新了&quot;</span>)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>可能有人就会说，那是不是在平时开发中，每一个模块都需要自己手动写开启 <code>HMR</code> 的代码呢？</p>
<p>答案肯定是否定的，社区已经针对这些有很成熟的解决方案了：</p>
<ul>
<li>如 <code>vue</code> 开发中，<code>vue-loader</code> 支持 <code>HMR</code> ，提供了开箱即用的体验</li>
<li>如 <code>react</code> 开发中， <code>react-refresh</code> 支持 <code>HMR</code> ，实时调整 <code>react</code> 组件</li>
</ul>
<h3 id="HMR-的原理"><a href="#HMR-的原理" class="headerlink" title="HMR 的原理"></a>HMR 的原理</h3><p><code>webpack-dev-server</code> 会创建两个服务：提供静态资源的服务（ express ）和 <code>Socket</code> 服务（ net.Socket ）</p>
<ul>
<li><code>express server</code> 负责直接提供静态资源的服务（打包后的资源直接被浏览器请求和解析）</li>
<li><code>HMR Socket Server</code> 是一个 <code>socket</code> 的长连接：<ul>
<li>长连接有一个最好的好处是建立连接后双方可以通信（服务器可以直接发送文件到客户端）</li>
<li>当服务器监听到对应的模块发生变化时，会生成两个文件 <code>.json（manifest文件）</code> 和 <code>.js文件（update chunk）</code></li>
<li>通过长连接，可以直接将这两个文件主动发送给客户端（浏览器）</li>
<li>浏览器拿到两个新的文件后，通过 <code>HMR runtime</code> 机制，加载这两个文件，并且针对修改的模块进行更新</li>
</ul>
</li>
</ul>
<p><code>HMR</code> 的原理图：</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107193450326.png" alt="image-20220107193450326"></p>
<h3 id="devServer中的其他配置"><a href="#devServer中的其他配置" class="headerlink" title="devServer中的其他配置"></a>devServer中的其他配置</h3><ul>
<li><code>host</code> 配置主机地址</li>
<li><code>port</code> 配置监听端口</li>
<li><code>open</code> 配置是否打开浏览器</li>
<li><code>compress</code> 配置是否为静态文件开启 <code>gzip compression</code></li>
</ul>
<h3 id="proxy"><a href="#proxy" class="headerlink" title="proxy"></a>proxy</h3><p><code>proxy</code> 是我们开发中非常常用的一个配置选项，它的目的设置代理来解决跨域访问的问题。</p>
<p>我们可以在 <code>devServer</code> 中，配置 <code>proxy</code> 属性进行设置：</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107194648139.png" alt="image-20220107194648139"></p>
<p>具体属性的含义：</p>
<ul>
<li><p><code>target</code> ：表示的是代理到的目标地址，比如 /api/moment会被代理到 <a target="_blank" rel="noopener" href="http://localhost:10086/api/moment">http://localhost:10086/api/moment</a></p>
</li>
<li><p><code>pathRewrite</code> ：默认情况下，我们的 <code>/api</code> 也会被写入到URL中，如果希望删除，可以使用 <code>pathRewrite</code></p>
</li>
<li><p><code>secure</code> ：默认情况下不接收转发到https的服务器上，如果希望支持，可以设置为false</p>
</li>
<li><p><code>changeOrigin</code> ：它表示是否更新代理后请求的 <code>headers</code> 中 <code>host</code> 地址</p>
</li>
</ul>
<h2 id="resolve-模块解析"><a href="#resolve-模块解析" class="headerlink" title="resolve 模块解析"></a>resolve 模块解析</h2><p><code>resolve</code> 用于设置模块如何被解析。</p>
<p><code>webpack</code> 能解析三种文件路径：</p>
<ol>
<li><p>绝对路径</p>
</li>
<li><p>相对路径</p>
</li>
<li><p>模块路径</p>
<p>在 <code>resolve.modules</code> 中指定的所有目录检索模块，默认值是 <code>[&#39;node_modules&#39;]</code></p>
<p>也可以设置别名。</p>
</li>
</ol>
<h3 id="解析过程"><a href="#解析过程" class="headerlink" title="解析过程"></a>解析过程</h3><p>如果没有后缀 先去 该名称的文件夹下查找是否存在 <code>index.js</code> 文件，再去找符合 <code>extensions</code>  ( <code>extension</code> 是 <code>resolve</code> 中的一个属性 ) 中后缀名的文件。</p>
<h3 id="resolve-中的-extensions-与-alias-配置"><a href="#resolve-中的-extensions-与-alias-配置" class="headerlink" title="resolve 中的 extensions 与 alias 配置"></a>resolve 中的 extensions 与 alias 配置</h3><p><code>extensions</code> 是解析到文件时自动添加扩展名，默认值是：<code>[&#39;.wasm&#39;, &#39;.mjs&#39;, &#39;.js&#39;, &#39;.json&#39;]</code>，如果我们代码中想要添加加载 <code>.vue</code> 或者 <code>jsx</code> 或者 <code>ts</code> 等文件时，我们必须自己写上扩展名。</p>
<p><code>alias</code> 用来配置路径的别名</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107201912032.png" alt="image-20220107201912032"></p>
<h2 id="webpack-配置文件的分离"><a href="#webpack-配置文件的分离" class="headerlink" title="webpack 配置文件的分离"></a>webpack 配置文件的分离</h2><p>在实际开发中，会在不同的环境中使用不同的 <code>webpack</code> 配置，因此我们可以建立如下的文件夹：</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107202339104.png" alt="image-20220107202339104"></p>
<p>其中，<code>webpack.comm.config.js</code> 用来存放通用配置，</p>
<p>然后我们将不同环境的配置抽离出来，放在对应环境的配置文件中。</p>
<p>最后，我们需要安装 <code>webpack-merge</code> 将不同的环境的配置文件，与通用配置文件合并：</p>
<p><code>webpack.dev.config.js</code>：</p>
<p><img src="https://codertzm.oss-cn-chengdu.aliyuncs.com/image-20220107202626573.png" alt="image-20220107202626573"></p>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p><code>webpack</code> 对于现在的前端来说，相当重要。这篇文章几乎涵盖了 <code>webpack</code> 的大部分配置，曾经的我学习 <code>webpack</code> 也认为它配置很多，学起来很杂，但其实疏通了整个结构就很清晰了。<code>webpack</code> 配置并不难，复杂的是它内部的实现原理。</p>

  </div>
</article>



        
          <div id="footer-post-container">
  <div id="footer-post">

    <div id="nav-footer" style="display: none">
      <ul>
         
          <li><a href="/">首页</a></li>
         
          <li><a href="/tags/">标签</a></li>
         
          <li><a href="/categories/">分类</a></li>
         
          <li><a href="/archives/">归档</a></li>
         
          <li><a target="_blank" rel="noopener" href="http://github.com/twitzz">项目</a></li>
         
          <li><a href="/about/">关于</a></li>
         
          <li><a href="/search/">搜索</a></li>
        
      </ul>
    </div>

    <div id="toc-footer" style="display: none">
      <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF-webpack"><span class="toc-number">1.</span> <span class="toc-text">什么是 webpack</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#webpack-%E5%87%BA%E7%8E%B0%E5%89%8D%E5%AD%98%E5%9C%A8%E5%93%AA%E4%BA%9B%E9%97%AE%E9%A2%98"><span class="toc-number">1.1.</span> <span class="toc-text">webpack 出现前存在哪些问题</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#webpack-%E7%9A%84%E5%AE%89%E8%A3%85"><span class="toc-number">2.</span> <span class="toc-text">webpack 的安装</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#webpack-%E7%9A%84%E9%BB%98%E8%AE%A4%E6%89%93%E5%8C%85"><span class="toc-number">3.</span> <span class="toc-text">webpack 的默认打包</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%A5%E5%8F%A3%E4%B8%8E%E5%87%BA%E5%8F%A3"><span class="toc-number">3.1.</span> <span class="toc-text">入口与出口</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B1%80%E9%83%A8%E4%BD%BF%E7%94%A8-webpack"><span class="toc-number">4.</span> <span class="toc-text">局部使用 webpack</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#webpack-%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="toc-number">5.</span> <span class="toc-text">webpack 的配置文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#webpack-%E7%9A%84%E4%BE%9D%E8%B5%96"><span class="toc-number">6.</span> <span class="toc-text">webpack 的依赖</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AFloader"><span class="toc-number">7.</span> <span class="toc-text">什么是loader</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#loader%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">8.</span> <span class="toc-text">loader的配置</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#loader-%E7%9A%84%E9%85%8D%E7%BD%AE%E9%A1%BA%E5%BA%8F"><span class="toc-number">9.</span> <span class="toc-text">loader 的配置顺序</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#less-%E7%9A%84%E5%A4%84%E7%90%86"><span class="toc-number">10.</span> <span class="toc-text">less 的处理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#less-loader"><span class="toc-number">10.1.</span> <span class="toc-text">less-loader</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#PostCSS-%E9%85%8D%E7%BD%AE"><span class="toc-number">11.</span> <span class="toc-text">PostCSS  配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#PostCSS-%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E4%BD%BF%E7%94%A8"><span class="toc-number">11.1.</span> <span class="toc-text">PostCSS 的命令行使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#postcss-loader"><span class="toc-number">11.2.</span> <span class="toc-text">postcss-loader</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E7%9A%84%E6%89%93%E5%8C%85"><span class="toc-number">12.</span> <span class="toc-text">静态资源的打包</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Plugin"><span class="toc-number">13.</span> <span class="toc-text">Plugin</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#CleanWebpackPlugin"><span class="toc-number">13.1.</span> <span class="toc-text">CleanWebpackPlugin</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%BD%BF%E7%94%A8"><span class="toc-number">13.1.1.</span> <span class="toc-text">使用</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#HtmlWebpackPlugin"><span class="toc-number">13.2.</span> <span class="toc-text">HtmlWebpackPlugin</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89HTML%E6%A8%A1%E6%9D%BF"><span class="toc-number">13.2.1.</span> <span class="toc-text">自定义HTML模板</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#DefinePlugin"><span class="toc-number">13.3.</span> <span class="toc-text">DefinePlugin</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#CopyWebpackPlugin"><span class="toc-number">13.4.</span> <span class="toc-text">CopyWebpackPlugin</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#mode%E9%85%8D%E7%BD%AE"><span class="toc-number">14.</span> <span class="toc-text">mode配置</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#babel-%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">15.</span> <span class="toc-text">babel 的配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E4%BD%BF%E7%94%A8"><span class="toc-number">15.1.</span> <span class="toc-text">babel 的命令行使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-%E6%8F%92%E4%BB%B6"><span class="toc-number">15.2.</span> <span class="toc-text">babel 插件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-%E9%A2%84%E8%AE%BE"><span class="toc-number">15.3.</span> <span class="toc-text">babel 预设</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-%E7%9A%84%E5%BA%95%E5%B1%82%E5%8E%9F%E7%90%86"><span class="toc-number">15.4.</span> <span class="toc-text">babel 的底层原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-loader"><span class="toc-number">15.5.</span> <span class="toc-text">babel-loader</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#babel-%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6"><span class="toc-number">15.6.</span> <span class="toc-text">babel 的配置文件</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AF%B9-vue-%E6%96%87%E4%BB%B6%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">16.</span> <span class="toc-text">对 vue 文件的配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#vue-%E6%89%93%E5%8C%85%E5%90%8E%E4%B8%8D%E5%90%8C%E7%89%88%E6%9C%AC%E8%A7%A3%E6%9E%90"><span class="toc-number">16.1.</span> <span class="toc-text">vue 打包后不同版本解析</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#vue-%E4%B8%AD-%E8%BF%90%E8%A1%8C%E6%97%B6-%E7%BC%96%E8%AF%91%E5%99%A8-vs-%E4%BB%85%E8%BF%90%E8%A1%8C%E6%97%B6"><span class="toc-number">16.2.</span> <span class="toc-text">vue 中 运行时 + 编译器 vs 仅运行时</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#devServer-%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">17.</span> <span class="toc-text">devServer 的配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#webpack-watch"><span class="toc-number">17.1.</span> <span class="toc-text">webpack watch</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#HMR%EF%BC%88-%E6%A8%A1%E5%9D%97%E7%83%AD%E6%9B%BF%E6%8D%A2-%EF%BC%89"><span class="toc-number">17.2.</span> <span class="toc-text">HMR（ 模块热替换 ）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#HMR-%E7%9A%84%E5%8E%9F%E7%90%86"><span class="toc-number">17.3.</span> <span class="toc-text">HMR 的原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#devServer%E4%B8%AD%E7%9A%84%E5%85%B6%E4%BB%96%E9%85%8D%E7%BD%AE"><span class="toc-number">17.4.</span> <span class="toc-text">devServer中的其他配置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#proxy"><span class="toc-number">17.5.</span> <span class="toc-text">proxy</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#resolve-%E6%A8%A1%E5%9D%97%E8%A7%A3%E6%9E%90"><span class="toc-number">18.</span> <span class="toc-text">resolve 模块解析</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A7%A3%E6%9E%90%E8%BF%87%E7%A8%8B"><span class="toc-number">18.1.</span> <span class="toc-text">解析过程</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#resolve-%E4%B8%AD%E7%9A%84-extensions-%E4%B8%8E-alias-%E9%85%8D%E7%BD%AE"><span class="toc-number">18.2.</span> <span class="toc-text">resolve 中的 extensions 与 alias 配置</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#webpack-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E7%9A%84%E5%88%86%E7%A6%BB"><span class="toc-number">19.</span> <span class="toc-text">webpack 配置文件的分离</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%80%BB%E7%BB%93"><span class="toc-number">20.</span> <span class="toc-text">总结</span></a></li></ol>
    </div>

    <div id="share-footer" style="display: none">
      <ul>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.facebook.com/sharer.php?u=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/"><i class="fab fa-facebook fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://twitter.com/share?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&text=webpack 入门"><i class="fab fa-twitter fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.linkedin.com/shareArticle?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&title=webpack 入门"><i class="fab fa-linkedin fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://pinterest.com/pin/create/bookmarklet/?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&is_video=false&description=webpack 入门"><i class="fab fa-pinterest fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" href="mailto:?subject=webpack 入门&body=Check out this article: https://danyuan30.gitee.io/2022/02/05/frontend/webpack/"><i class="fas fa-envelope fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://getpocket.com/save?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&title=webpack 入门"><i class="fab fa-get-pocket fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://reddit.com/submit?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&title=webpack 入门"><i class="fab fa-reddit fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.stumbleupon.com/submit?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&title=webpack 入门"><i class="fab fa-stumbleupon fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://digg.com/submit?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&title=webpack 入门"><i class="fab fa-digg fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="http://www.tumblr.com/share/link?url=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&name=webpack 入门&description="><i class="fab fa-tumblr fa-lg" aria-hidden="true"></i></a></li>
  <li><a class="icon" target="_blank" rel="noopener" href="https://news.ycombinator.com/submitlink?u=https://danyuan30.gitee.io/2022/02/05/frontend/webpack/&t=webpack 入门"><i class="fab fa-hacker-news fa-lg" aria-hidden="true"></i></a></li>
</ul>

    </div>

    <div id="actions-footer">
        <a id="menu" class="icon" href="#" onclick="$('#nav-footer').toggle();return false;"><i class="fas fa-bars fa-lg" aria-hidden="true"></i> 菜单</a>
        <a id="toc" class="icon" href="#" onclick="$('#toc-footer').toggle();return false;"><i class="fas fa-list fa-lg" aria-hidden="true"></i> 目录</a>
        <a id="share" class="icon" href="#" onclick="$('#share-footer').toggle();return false;"><i class="fas fa-share-alt fa-lg" aria-hidden="true"></i> 分享</a>
        <a id="top" style="display:none" class="icon" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fas fa-chevron-up fa-lg" aria-hidden="true"></i> 返回顶部</a>
    </div>

  </div>
</div>

        
        <footer id="footer">
  <div class="footer-left">
    Copyright &copy;
    
    
    2021-2022
    柯里的语法糖
  </div>
  <div class="footer-right">
    <nav>
      <ul>
        <!--
       --><li><a href="/">首页</a></li><!--
     --><!--
       --><li><a href="/tags/">标签</a></li><!--
     --><!--
       --><li><a href="/categories/">分类</a></li><!--
     --><!--
       --><li><a href="/archives/">归档</a></li><!--
     --><!--
       --><li><a target="_blank" rel="noopener" href="http://github.com/twitzz">项目</a></li><!--
     --><!--
       --><li><a href="/about/">关于</a></li><!--
     --><!--
       --><li><a href="/search/">搜索</a></li><!--
     -->
      </ul>
    </nav>
  </div>
</footer>

    </div>
    <!-- styles -->



  <link rel="preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" crossorigin="anonymous" onload="this.onload=null;this.rel='stylesheet'"/>


    <!-- jquery -->
 
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin="anonymous"></script> 




<!-- clipboard -->

  
    <script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.7/clipboard.min.js" crossorigin="anonymous"></script> 
  
  <script type="text/javascript">
  $(function() {
    // copy-btn HTML
    var btn = "<span class=\"btn-copy tooltipped tooltipped-sw\" aria-label=\"复制到粘贴板!\">";
    btn += '<i class="far fa-clone"></i>';
    btn += '</span>'; 
    // mount it!
    $(".highlight table").before(btn);
    var clip = new ClipboardJS('.btn-copy', {
      text: function(trigger) {
        return Array.from(trigger.nextElementSibling.querySelectorAll('.code')).reduce((str,it)=>str+it.innerText+'\n','')
      }
    });
    clip.on('success', function(e) {
      e.trigger.setAttribute('aria-label', "复制成功!");
      e.clearSelection();
    })
  })
  </script>


<script src="/js/main.js"></script>

<!-- search -->

<!-- Google Analytics -->

<!-- Baidu Analytics -->

<!-- Cloudflare Analytics -->

<!-- Umami Analytics -->

<!-- Disqus Comments -->

<!-- utterances Comments -->

</body>
</html>
